
package com.csxy.news.util;

import java.util.Collection;

/*
* 自定义的数学工具类
*/

public class MathUtil{
	
	/*
	* 功能：产生[m,n]之间的随机整数
	* 参数: n>m,且为整数
    * 返回值：返回[m,n]之间的随机整数	
	*/
	public static int random(int m,int n){
		
		double d=Math.random();//[0,1)
		   
		d=d*(n-m)+m;//[m,n) --->[m,n]
		
		   //四舍五入
		d=Math.round(d); //[m,n]之间小数
		   //将小数强制转换成整数
		
		int x=(int)d;
		
		return x;//将结果返回给调用者
		
	}
	
	/**
	 * 获取一个字符串中的1个随机字符
	 * @param array
	 * @return
	 */
	public static char randomChar(String s){
		
		int index=random(0, s.length()-1);
		return s.charAt(index);		
	}
	
	/**
	 * 获取一个字符串中的由多个随机字符组成的子串
	 * @param array
	 * @return
	 */
	public static String randomSubString(String s,int count){
		
		StringBuilder sb=new StringBuilder();
		for (int i = 0; i < count; i++) {
			char c = randomChar(s);
			sb.append(c);
		}
		
		return sb.toString();
				
	}
	
	/**
	 * 获取一个泛型数组中的随机元素
	 * @param array
	 * @return
	 */
	public static <T> T randomElement(T[] array){
		
		int index=random(0, array.length-1);
		return array[index];		
	}
	
	
	/**
	 * 获取一个泛型集合中的随机元素
	 * @param array
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static <T> T randomElement(Collection<T> collection){
		
		Object[] array=collection.toArray();
		Object o=randomElement(array);
		return (T)o;		
	}
	
	
	/*
	* 功能：判断n是否为素数
	* 参数：n为自然数
	* 返回值：true=素数，false=非素数
	*/
	public static boolean isPrimeNumber(int n){
		
		if(n<1){
			return false;
		}
		
		//依据【2，n)判断是否能整除n
		for(int m=2;m<n;m++){
				
			if(n % m ==0){
				return false;
			}
		}
		return true;
		
	}

	/*
	* 功能：判断year是否为闰年 
	* 1、能被4整除但不能被100整除
    * 2、能被400整 除
	* 参数：指定年year
	* 返回值：true=闰年，false=非闰年
	*/
	public static boolean isLeapYear(int year){
		 
		return ( (year % 4 ==0) && ( year % 100!=0) ) || ( year % 400==0  );
		 
	}
	
	/** 求fibonacci数列第n项的值
	 *  fibonacci数列通项公式：v[1]=v[2]=1 ,v[n]=v[n-1]+v[n-2] (n>2)
	 * @param n fibonacci数列的第n项 n是自然数
	 * @return 第n项的值
	 */
	public static int fibonacciAt(int n){
	    
		if(n<1){
			return 0;
		}
		if(n==1 || n==2){
			//归的条件
			return 1;
		}
		//递推
		return fibonacciAt(n-1)+fibonacciAt(n-2);
	}
	/**
	 * 求n!的值
	 * @param n
	 * @return
	 */
	public static int factorial(int n){
		
		//回归的条件
		if(n<1){
			return 0;
		}
		if(n==1){
			return 1;
		}
		
		return n*factorial(n-1);
		
	}

	/** 正整数因子分解
	 *  如：90=2*3*3*5
	 * @param n
	 * @return 返回由各素数因子构成的数组
	 */
	public static int[] toPrimeFactors(int n) {
		int[] rets=new int[0];
		int k=2;
		while (k<=n) {
			//(1)如果这个质数恰等于n，则说明分解质因数的过程已经结束，打印出即可。
			if (n == k) {
				rets=ArrayUtil.add(k, rets);
				break;
			} else {
				//(2)如果n<>k，但n能被k整除，则应打印出k的值，并用n除以k的商,作为新的正整数你n,重复执行第一步
				if (n % k == 0) {
					n = n / k;
					rets=ArrayUtil.add(k, rets);//保存素数因子
					continue;
				}else{
					k+=1;
					continue;
				}
			} 
			
		}//end while
		
		return rets;
		
	}
	
	/**
	 * 判断一个数是否为平方数
	 * @param n n是自然数
	 * @return
	 */
	public static boolean isSquareNumber(int n){
		
		boolean b=false;
		
		for (int i = 1; i <= n; i++) {
			if (i*i==n) {
				b=true;
				break;
			}
		}
		
		return b;
	}

	
}